﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace HousingDistribution
{
    class PersonSortInfoProc
    {
        public void Proc(PersonInfo person)
        {
            PersonSortInfo info = new PersonSortInfo();
            info.idperson = person.idperson;

            if (person.type == PersonTypeEnum.ArmMan)
            {
                ProcArmManGradeAndGradeTime(ref info, person);

                info.sortCurGradeBeforeTime = ProcCurGradeBeforTime(person, info.sortGradeTime);
            }
            else if (person.type == PersonTypeEnum.Staff)
            {
                ProcStaffGrade(ref info, person);
                info.sortCurGradeBeforeTime = ProcCurGradeBeforTime(person, info.sortGradeTime);
            }
            else if (person.type == PersonTypeEnum.Worker)
            {
                ProcWorkerGrade(ref info, person);
            }
            else if (person.type == PersonTypeEnum.NCO)
            {
                ProcNCOGrade(ref info, person);
            }
            else
            {
                return;
            }

            info.sortWorkTime = ProcWorkTime(person);

            info.sortSignupTime = person.signupTime;
            
            info.sortMateName = person.mateInfo.name;

            info.sortEvaluationWeight = DataDictionary.Instance().GetEvaluationWeight(person.evaluation);

            info.sortUnitWeight = DataDictionary.Instance().GetUnitWeight(person.unit);

            StorePersonSortInfo(info);
        }

        void StorePersonSortInfo(PersonSortInfo info)
        {
            try
            {
                //首先判断存不存在该记录
                StringBuilder querySql = new StringBuilder("select * from personsortinfo where idperson = '");
                querySql.Append(info.idperson.ToString());
                querySql.Append("'");

                int count = DBProc.Instance().ReadData(querySql.ToString()).Tables[0].Rows.Count;

                //若没有对应记录，则插入；否则更新
                if (count == 0)
                {
                    string sqlStr = this.sqlCreator.InsertSql(info);
                    DBProc.Instance().Excute(sqlStr);
                }
                else
                {
                    string sqlStr = this.sqlCreator.UpdateSql(info);
                    DBProc.Instance().Excute(sqlStr);
                }
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
            }
        }

        void DeletePersonSortInfo(int personid)
        {
            try
            {
                //首先判断存不存在该记录
                StringBuilder sql = new StringBuilder("delete from personsortinfo where idperson = '");
                sql.Append(personid.ToString());
                sql.Append("'");

                DBProc.Instance().Excute(sql.ToString());
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
            }
        }

        void ProcArmManGradeAndGradeTime(ref PersonSortInfo info, PersonInfo person)
        {
            //非技术7技，返回teckrank。
            string grade = RankMapping.Instance().GetGradeByTechRank(person.techRank, person.techTitle);
            int techRankWeight = DataDictionary.Instance().GetGradeWeight(grade);
            int adminDutyWeight = DataDictionary.Instance().GetGradeWeight(person.adminDuty);

            if (techRankWeight == 0 && adminDutyWeight == 0)
            {
                info.sortGrade = null;
                info.sortGradeWeight = 0;
            }
            //取两者级别较高的。
            else if (techRankWeight == adminDutyWeight)
            {
                if (grade.Contains("正"))
                    info.sortGrade = grade;
                else
                    info.sortGrade = person.adminDuty;
                    
                info.sortGradeWeight = adminDutyWeight;
            }
            else if (techRankWeight > adminDutyWeight)
            {
                info.sortGrade = grade;
                info.sortGradeWeight = techRankWeight;
            }
            else
            {
                info.sortGrade = person.adminDuty;
                info.sortGradeWeight = adminDutyWeight;
            }

            ProcArmManMarital(ref info, person.marital, info.sortGrade, person.withArmy);

            info.sortGradeTime = GetGradeTime(person.adminDutyTime, person.techRankTime, person.techTitleTime);
        }

        //处理婚姻状况
        //已婚、未婚、离异有子女、离异无子女、丧偶。
        //未婚和离异无子女，排队时降一级，师-团，团-营，营以下无分房资格。
        //已婚、离异有子女，正常分。
        void ProcArmManMarital(ref PersonSortInfo info, PersonMaritalEnum marital, string grade, WithArmyStatusEnum witharmy)
        {
            if (grade == null)
                return;

            switch (marital)
            {
                case PersonMaritalEnum.Married:
                case PersonMaritalEnum.DivorcedWithoutChild:
                case PersonMaritalEnum.Unmarried:
                    info.sortGradeWeight -= DataDictionary.Instance().GetGradeDownValue(marital, grade, witharmy);
                    break;

                default:
                    return;
            }
        }

        //职员通过行政职务，技术职称，工龄对应军人grade，进行无配偶处理
        void ProcStaffGrade(ref PersonSortInfo info, PersonInfo person)
        {
            info.sortGrade = DataDictionary.Instance().GetStaffGrade(person);
            info.sortGradeWeight = DataDictionary.Instance().GetGradeWeight(info.sortGrade);
            ProcArmManMarital(ref info, person.marital, info.sortGrade, person.withArmy);
        }
        //工人通过工龄对应军人grade，进行无配偶处理
        void ProcWorkerGrade(ref PersonSortInfo info, PersonInfo person)
        {
            info.sortGrade = DataDictionary.Instance().GetGradeByServiceLen(ServiceLengthCount.Instance().ServiceLength(person));
            info.sortGradeWeight = DataDictionary.Instance().GetGradeWeight(info.sortGrade);
            ProcArmManMarital(ref info, person.marital, info.sortGrade, person.withArmy);
        }
        //士官通过工龄对应军人grade，进行无配偶处理
        void ProcNCOGrade(ref PersonSortInfo info, PersonInfo person)
        {
            info.sortGrade = DataDictionary.Instance().NCOGetGradeByServiceLen(ServiceLengthCount.Instance().ServiceLength(person));
            info.sortGradeWeight = DataDictionary.Instance().GetGradeWeight(info.sortGrade);
            ProcArmManMarital(ref info, person.marital, info.sortGrade, person.withArmy);
        }
        
        public DateTime GetGradeTime( DateTime adminDutyTime, DateTime techRankTime, DateTime techTitleTime)
        {
            DateTime techTime = DateProc.InvalidDate();
            DateTime gradeTime = DateProc.InvalidDate();
            //时间2（技术级别任命时间） 和 时间3 （技术职务任命时间）都有效，则取时间晚的和时间1 （行政职务任命时间）进行比较， 取时间早的比较
            //这里的无效时间为 2100年1月1日，因此不管时间1是否有效，均不影响处理流程
            if (techRankTime.Equals(DateProc.InvalidDate()) == false && techTitleTime.Equals(DateProc.InvalidDate()) == false)
            {
                techTime = this.dateProc.GetLaterDate(techRankTime, techTitleTime);

                gradeTime = this.dateProc.GetEarlierDate(techTime, adminDutyTime);
            }
            //技术级别时间有效， 技术职务时间无效，取技术级别时间
            else if (techRankTime.Equals(DateProc.InvalidDate()) == false && techTitleTime.Equals(DateProc.InvalidDate()) == true)
            {
                techTime = techRankTime;

                gradeTime = this.dateProc.GetEarlierDate(techTime, adminDutyTime);
            }
            //技术级别时间无效， 技术职务时间有效，这种分支不可能，如果出现则应该检查数据。 取技术职务时间
            else if (techRankTime.Equals(DateProc.InvalidDate()) == false && techTitleTime.Equals(DateProc.InvalidDate()) == true)
            {
                techTime = techTitleTime;

                gradeTime = this.dateProc.GetEarlierDate(techTime, adminDutyTime);
            }
            //两个都无效,这种分支不可能，如果出现则应该检查数据。 但不影响处理
            else
            {
                gradeTime = this.dateProc.GetEarlierDate(DateProc.InvalidDate(), adminDutyTime);
            }
            return gradeTime;
        }

        //任现职的副职时间的处理
        DateTime ProcCurGradeBeforTime(PersonInfo personInfo, DateTime gradeTime)
        {
            //处理现副职时间无效（excel对应字段为空）的数据
            if (DateTime.Compare(personInfo.curRankBeforeTime, DateProc.InvalidDate()) == 0)
            {
                int year = 0;

                if ((personInfo.techRank != null && DataDictionary.Instance().RankInfoForCurRankBeforeTimeMissing().Contains(personInfo.techRank) && (personInfo.techRank != ""))
                    || (personInfo.adminDuty != null && DataDictionary.Instance().RankInfoForCurRankBeforeTimeMissing().Contains(personInfo.adminDuty) && (personInfo.adminDuty != ""))
                    )
                {
                    year = 3;
                }
                else
                {
                    year = 4;
                }
                //有些人员的gradeTime可能无效（初始化为 0001-01-01）
                if (gradeTime.Year > year)
                    return gradeTime.AddYears(-year);
                else
                    return personInfo.curRankBeforeTime;
            }
            else
                return personInfo.curRankBeforeTime;
        }

        //工作时间的处理：比较工作时间，上学时间， 取较早时间为工作时间
        DateTime ProcWorkTime(PersonInfo person)
        {
            return this.dateProc.GetEarlierDate(person.workTime, person.schoolTime);
        }

        //判断是否双职工
        public static bool MateIsOurEmployee(MateInfo mate)
        {
            foreach (string s in DataDictionary.Instance().Unit())
            {
                if (mate.unit.Equals(s))
                    return true;
            }

            return false;
        }

        DateProc dateProc = new DateProc("YY-MM-DD");

        ObjectParser parser = new PersonParserFromMySql();

        DataStruct2SQL sqlCreator = new DataStruct2SQL();
    }
}
